#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/stdlib/log.hpp"

namespace acl {

	static bool m_bOpened = false;

	void log::open(const char* recipients, const char* procname /* = unknown */,
		const char* cfg /* = NULL */)
	{
		if (m_bOpened)
			return;

		acl_assert(recipients);
		acl_assert(procname);

		const char* ptr = strrchr(procname, '/');
		if (ptr)
			procname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(procname, '\\');
			if (ptr)
				procname = ptr + 1;
		}
#endif

		acl_msg_open(recipients, procname);
		m_bOpened = true;
		if (cfg)
			acl_debug_init(cfg);
	}

	void log::close(void)
	{
		if (m_bOpened) {
			acl_msg_close();
			acl_debug_end();
			m_bOpened = false;
		}
	}

	void log::stdout_open(bool onoff)
	{
		acl_msg_stdout_enable(onoff ? 1 : 0);
	}

	void log::msg1(const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vmsg2(fmt, ap);
		va_end(ap);
	}

	void log::vmsg2(const char* fmt, va_list ap)
	{
		acl_msg_info2(fmt, ap);
	}

	void log::msg4(const char* fname, int line, const char* func,
		const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vmsg5(fname, line, func, fmt, ap);
		va_end(ap);
	}

	void log::vmsg5(const char* fname, int line, const char* func,
		const char* fmt, va_list ap)
	{
		const char* ptr = strrchr(fname, '/');
		if (ptr)
			fname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(fname, '\\');
			if (ptr)
				fname = ptr + 1;
		}
#endif
		acl::string s;
		s.format("%s(%d), %s: ", fname, line, func);
		s.vformat_append(fmt, ap);
		acl_msg_info("%s", s.c_str());
	}

	void log::msg3(size_t section, size_t level, const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vmsg4(section, level, fmt, ap);
		va_end(ap);
	}

	void log::vmsg4(size_t section, size_t level, const char* fmt, va_list ap)
	{
		if (acl_do_debug((int) section, (int) level))
			vmsg2(fmt, ap);
	}

	void log::msg6(size_t section, size_t level, const char* fname,
		int line, const char* func, const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vmsg7(section, level, fname, line, func, fmt, ap);
		va_end(ap);
	}

	void log::vmsg7(size_t section, size_t level, const char* fname,
		int line, const char* func, const char* fmt, va_list ap)
	{
		if (!acl_do_debug((int) section, (int) level))
			return;

		const char* ptr = strrchr(fname, '/');
		if (ptr)
			fname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(fname, '\\');
			if (ptr)
				fname = ptr + 1;
		}
#endif

		acl::string s;
		s.format("%s(%d), %s: ", fname, line, func);
		s.vformat_append(fmt, ap);
		acl_msg_info("%s", s.c_str());
	}

	void log::warn1(const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vwarn2(fmt, ap);
		va_end(ap);
	}

	void log::vwarn2(const char* fmt, va_list ap)
	{
		acl_msg_warn2(fmt, ap);
	}

	void log::warn4(const char* fname, int line, const char* func,
		const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vwarn5(fname, line, func, fmt, ap);
		va_end(ap);
	}

	void log::vwarn5(const char* fname, int line, const char* func,
		const char* fmt, va_list ap)
	{
		const char* ptr = strrchr(fname, '/');
		if (ptr)
			fname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(fname, '\\');
			if (ptr)
				fname = ptr + 1;
		}
#endif

		acl::string s;
		s.format("%s(%d), %s: ", fname, line, func);
		s.vformat_append(fmt, ap);
		acl_msg_warn("%s", s.c_str());
	}

	void log::error1(const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		verror2(fmt, ap);
		va_end(ap);
	}

	void log::verror2(const char* fmt, va_list ap)
	{
		acl_msg_error2(fmt, ap);
	}

	void log::error4(const char* fname, int line, const char* func,
		const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		verror5(fname, line, func, fmt, ap);
		va_end(ap);
	}

	void log::verror5(const char* fname, int line, const char* func,
		const char* fmt, va_list ap)
	{
		const char* ptr = strrchr(fname, '/');
		if (ptr)
			fname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(fname, '\\');
			if (ptr)
				fname = ptr + 1;
		}
#endif

		acl::string s;
		s.format("%s(%d), %s: ", fname, line, func);
		s.vformat_append(fmt, ap);
		acl_msg_error("%s", s.c_str());
	}

	void log::fatal1(const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vfatal2(fmt, ap);
		va_end(ap);
	}

	void log::vfatal2(const char* fmt, va_list ap)
	{
		acl_msg_fatal2(fmt, ap);
	}

	void log::fatal4(const char* fname, int line, const char* func,
		const char* fmt, ...)
	{
		va_list ap;

		va_start(ap, fmt);
		vfatal5(fname, line, func, fmt, ap);
		va_end(ap);
	}

	void log::vfatal5(const char* fname, int line, const char* func,
		const char* fmt, va_list ap)
	{
		const char* ptr = strrchr(fname, '/');
		if (ptr)
			fname = ptr + 1;
#ifdef	WIN32
		if (ptr == NULL)
		{
			ptr = strrchr(fname, '\\');
			if (ptr)
				fname = ptr + 1;
		}
#endif

		acl::string s;
		s.format("%s(%d), %s: ", fname, line, func);
		s.vformat_append(fmt, ap);
		acl_msg_fatal("%s", s.c_str());
	}

} // namespace acl
